package com.lost.octopus.es.processor.config;

import com.lost.octopus.es.processor.constant.enums.LimitSyncSchedulerKeyEnum;
import com.lost.octopus.es.processor.scheduler.AbstractSyncScheduler;
import lombok.extern.log4j.Log4j2;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.context.annotation.Configuration;

import java.util.EnumMap;
import java.util.Map;

/**
 * 同步调度AOP
 * @author zhangbh
 **/
@Log4j2
@Aspect
@Configuration
public class SyncSchedulerAop {

    /**
     * 正在执行任务的调度
     */
    private static final Map<LimitSyncSchedulerKeyEnum, Long> TASK_ON_MAP = new EnumMap<>(LimitSyncSchedulerKeyEnum.class);

    @Around("execution( * com.lost.octopus.es.processor.scheduler.AbstractSyncScheduler+.*(..)) && "
        + "@annotation(com.xxl.job.core.handler.annotation.XxlJob)")
    public Object roundCheckSync(ProceedingJoinPoint point) throws Throwable {
        // 不是同步调度实体，直接跳过
        Object target = point.getTarget();
        if (!(point.getTarget() instanceof AbstractSyncScheduler)) {
            return point.proceed();
        }
        // 转换实体
        AbstractSyncScheduler obj = (AbstractSyncScheduler) target;

        // 业务key
        LimitSyncSchedulerKeyEnum key = obj.businessKey();

        long jobId = Thread.currentThread().getId();
        // 正在执行任务的ID
        Long taskOnId = TASK_ON_MAP.get(key);
        // 还未执行，先保存
        if (taskOnId == null) {
            TASK_ON_MAP.put(key, jobId);
        } else {
            // 在进行任务中，直接退出
            log.info("当前业务【{}】正在执行任务中，直接退出", obj.businessKey().getLabel());
            return null;
        }
        Object returnVal = null;
        try {
            returnVal = point.proceed();
        } catch (Exception e) {
            log.error("【" + obj.businessKey().getLabel() + "】 调度执行报错", e);
        }
        // 任务执行完毕要删除对应的运行状态
        TASK_ON_MAP.remove(key);
        return returnVal;
    }

}
